<!--员工管理 UserManagement-->
<template>
  <div class='page_format'>
    <div class="my_Select">
      <el-form :inline="true" class="search-form">
        <el-form-item>
          <el-button class="bt-color-tjd" type="primary" v-if="is_show_button('button_user_add')"
                     @click="saveDataForm">添加
          </el-button>
        </el-form-item>
        <el-form-item>
          <el-select v-model="roleId" placeholder="员工职务" style="width: 150px;" size="small" clearable
                     @change="handleQuery">
            <el-option
              v-for="(item, index) in roleData"
              :key="index"
              :label="`${item.roleName}`"
              :value="item.roleId"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-select v-model="sex" placeholder="员工性别" style="width: 110px;" size="small" clearable
                     @change="handleQuery">
            <el-option
              v-for="(item, index) in sexData"
              :key="index"
              :label="`${item.label}`"
              :value="item.value"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-select v-model="status" placeholder="账号状态" style="width: 110px;" size="small" clearable
                     @change="handleQuery">
            <el-option
              v-for="(item, index) in statusData"
              :key="index"
              :label="`${item.label}`"
              :value="item.value"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-input style="width:180px;margin-right:8px" size="small" placeholder="姓名/账号/手机/邮箱"
                    v-model.number="queryValue"
                    clearable></el-input>
          <el-button size="small" @click="handleQuery" icon="el-icon-search" type="primary">查询</el-button>
        </el-form-item>
      </el-form>
    </div>
    <el-table :data="list" border style="width: 100%">
      <el-table-column type="index" :index="sort" label="序号" width="50"></el-table-column>

      <el-table-column prop="nickName" label="员工姓名"></el-table-column>
      <el-table-column prop="sex" label="性别">
        <template v-slot="scope">
          <span>{{ getSexText(scope.row.sex) }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="roleId" label="当前职务">
        <template v-slot="scope">
          <span>{{ getRoleText(scope.row.roleId) }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="userName" label="登录账号"></el-table-column>
      <el-table-column prop="phoneNumber" label="手机号"></el-table-column>
      <el-table-column prop="createTime" label="创建时间"></el-table-column>
      <el-table-column fixed="right" label="操作" width="100" align="center">
        <template v-slot="scope">
          <div>
            <el-button v-if="is_show_button('button_user_setting_permissions')" @click="handleSetPermissions(scope.row)" type="text" size="small">
              设置权限
            </el-button>
          </div>
          <div>
            <el-button v-if="is_show_button('button_user_edit')" @click="handleClick(scope.row)" type="text" size="small">
              编辑
            </el-button>
            <el-button v-if="is_show_button('button_user_disable')" @click="changeStatus(scope.row)" type="text" size="small">
              {{ scope.row.status === "0" ? "禁用" : "启用" }}
            </el-button>
          </div>
          <div>
            <el-button v-if="is_show_button('button_user_reset_password')" @click="resetPassword(scope.row)" type="text" size="small">
              重置密码
            </el-button>
          </div>
          <el-button v-if="is_show_button('button_user_delete')" @click="handleButtonClick(scope.row)" type="text" size="small">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <div>
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="pageNum"
        :page-sizes="[10, 20, 30, 50]"
        :page-size="pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total">
      </el-pagination>
    </div>

    <el-dialog :title="form.userId ?'修改':'添加'" :visible.sync="dialogFormVisible" center width="500px"
               @close="closeDialog">
      <el-form :model="form" :rules="rules" ref="dialogForm">
        <el-form-item label="登录账号：" :label-width="formLabelWidth" prop="userName">
          <el-input v-model="form.userName" autocomplete="off" placeholder="请填写登录账号"
                    style="width: 100%;"></el-input>
        </el-form-item>
        <el-form-item v-if="!form.userId" label="登录密码：" :label-width="formLabelWidth" prop="password">
          <el-input v-model="form.password" autocomplete="off" placeholder="请填写登录密码"
                    style="width: 100%;"></el-input>
        </el-form-item>
        <el-form-item label="员工姓名：" :label-width="formLabelWidth" prop="nickName">
          <el-input v-model="form.nickName" autocomplete="off" placeholder="请填写员工姓名"
                    style="width: 100%;"></el-input>
        </el-form-item>
        <el-form-item label="手机号：" :label-width="formLabelWidth" prop="phoneNumber">
          <el-input v-model="form.phoneNumber" autocomplete="off" placeholder="请填写手机号"
                    style="width: 100%;"></el-input>
        </el-form-item>
        <el-form-item label="邮箱地址：" :label-width="formLabelWidth" prop="email">
          <el-input v-model="form.email" autocomplete="off" placeholder="请填写邮箱地址"
                    style="width: 100%;"></el-input>
        </el-form-item>
        <el-form-item label="性别：" :label-width="formLabelWidth" prop="sex">
          <template>
            <el-radio v-model="form.sex" label="0">男</el-radio>
            <el-radio v-model="form.sex" label="1">女</el-radio>
          </template>
        </el-form-item>
        <el-form-item label="当前职务：" :label-width="formLabelWidth" prop="roleId">
          <el-select v-model="form.roleId" placeholder="请选择当前职务" style="width: 100%;">
            <el-option
              v-for="item in roleData"
              :key="item.id"
              :label="`${item.roleName}`"
              :value="item.roleId"
            ></el-option>
          </el-select>
        </el-form-item>
      </el-form>

      <!-- 底部按钮 -->
      <div slot="footer" class="dialog-footer">
        <el-button @click="closeDialog" :disabled="submitLoading">取 消</el-button>
        <el-button class="bt-color-tjd" v-if="is_show_button('button_user_edit')" type="primary"
                   @click="saveDataApi" :loading="submitLoading">确 定
        </el-button>
      </div>
    </el-dialog>

    <el-dialog title="设置权限" :visible.sync="setPermissionsShow" center width="900px"
               @close="closeDialog">
        <div>
          <el-divider :style="{ 'font-size': '16px', 'margin-top': '20px', 'margin-bottom': '20px' }"
                      content-position="left" >员工信息</el-divider>
          <el-form :model="form" :label-width="formLabelWidth" size="mini" class="detail">
            <el-form-item label="员工姓名：" :label-width="formLabelWidth" style="display: inline-block; width: 30%;">
              <span >{{ form.nickName }}</span>
            </el-form-item>
            <el-form-item label="当前职务：" :label-width="formLabelWidth" style="display: inline-block; width: 40%;">
              <span>{{ getRoleText(form.roleId) }}</span>
            </el-form-item>
          </el-form>
        </div>
        <el-divider :style="{ 'font-size': '16px', 'margin-top': '20px', 'margin-bottom': '20px' }"
                    content-position="left" >权限设置</el-divider>
      <el-form :model="form" :rules="rules" ref="dialogForm">
          <el-tree
            ref="menuTree"
            :data="menuTreeData"
            show-checkbox
            node-key="menuId"
            :props="defaultProps"
            @check-change="handleCheckChange"
          >
          </el-tree>
      </el-form>

      <!-- 底部按钮 -->
      <div slot="footer" class="dialog-footer">
        <el-button @click="closeDialog" :disabled="submitLoading">取 消</el-button>
        <el-button @click="resetSelection">重置</el-button>
        <el-button class="bt-color-tjd" v-if="is_show_button('button_user_setting_permissions')" type="primary"
                   @click="saveSetPermissionsDataApi" :loading="submitLoading">确 定
        </el-button>
      </div>
    </el-dialog>
    <Toast :dialogVisible="dialogVisible" @isDelete="deleteDataApi"></Toast>
  </div>
</template>

<script>
import { post } from '@/api/my_axios'
import { changSort } from '@/utils/aqi'

export default {
  name: '',
  data () {
    return {
      setPermissionsShow: false, // 权限按钮loading
      submitLoading: false, // 按钮loading
      dialogFormVisible: false,
      dialogVisible: false,
      dialogShowS: false,
      form: {
        userId: '',
        userName: '',
        password: '',
        status: '',
        remark: '',
        nickName: '',
        userType: '',
        email: '',
        phoneNumber: '',
        sex: '',
        roleId: '',
        menuIdList: []
      },
      list: [],
      roleData: [],
      menuData: [],
      infoForm: {},
      checkedMenuIds: [], // 已勾选的菜单ID
      menuTreeData: [], // 菜单树数据
      defaultProps: { // 默认属性配置
        children: 'children', // 子节点字段
        label: 'menuName', // 显示名称字段
        key: 'menuId' // 唯一标识字段
      },
      formLabelWidth: '140px',
      pageSize: 20,
      pageNum: 1,
      total: 0,
      id: '',
      queryValue: '',
      roleId: '',
      sex: '',
      status: '',
      // rules: {
      //   companyId: [{ required: true, message: '必填项不能为空！', trigger: 'change' }],
      //   userName: [{ required: true, message: '必填项不能为空！', trigger: 'change' }],
      //   password: [{ required: true, message: '必填项不能为空！', trigger: 'change' }],
      //   nickName: [{ required: true, message: '必填项不能为空！', trigger: 'change' }],
      //   phoneNumber: [{ required: true, message: '必填项不能为空！', trigger: 'change' }],
      //   sex: [{ required: true, message: '必填项不能为空！', trigger: 'change' }],
      //   roleId: [{ required: true, message: '必填项不能为空！', trigger: 'change' }]
      // },
      rules: {
        userName: [
          { required: true, message: '登录账号不能为空', trigger: 'blur' },
          { min: 4, max: 32, message: '登录账号长度需在4到32个字符之间', trigger: 'blur' },
          { pattern: /^[a-zA-Z0-9]+$/, message: '登录账号仅支持数字和字母', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '密码不能为空', trigger: 'blur' },
          { min: 6, max: 32, message: '密码必须是6到32个字符之间的字母+数字+符号', trigger: 'blur' },
          {
            pattern: /^[a-zA-Z0-9!@#$%^&*()\-+]+$/,
            message: '密码仅支持数字、字母和特殊符号 (!@#$%^&*()-+)',
            trigger: 'blur'
          },
          {
            validator: (rule, value, callback) => {
              if (!/[A-Za-z]/.test(value)) {
                callback(new Error('密码必须包含字母'))
              } else if (!/[0-9]/.test(value)) {
                callback(new Error('密码必须包含数字'))
              } else if (!/[!@#$%^&*()\-+]/.test(value)) {
                callback(new Error('密码必须包含特殊符号 (!@#$%^&*()-+)'))
              } else {
                callback()
              }
            },
            trigger: 'blur'
          }
        ],
        nickName: [
          { required: true, message: '员工姓名不能为空', trigger: 'blur' },
          { min: 2, max: 32, message: '员工姓名长度需在2到32个字符之间', trigger: 'blur' },
          { pattern: /^\S+$/, message: '员工姓名中不能包含空格', trigger: 'blur' }
        ],
        phoneNumber: [
          { required: true, message: '手机号不能为空', trigger: 'blur' },
          { pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确,应为11位数字', trigger: 'blur' }
        ],
        email: [
          { max: 50, message: '邮箱地址长度不能超过50个字符', trigger: 'blur' },
          {
            pattern: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
            message: '邮箱格式不正确，应为：xx@xx.xx',
            trigger: 'blur'
          }
        ],
        sex: [{ required: true, message: '必填项不能为空！', trigger: 'change' }],
        roleId: [{ required: true, message: '必填项不能为空！', trigger: 'change' }]
      },
      statusData: [
        { value: '0', label: '启用' },
        { value: '1', label: '禁用' }
      ],
      sexData: [
        { value: '0', label: '男' },
        { value: '1', label: '女' }
      ]
    }
  },

  mounted () {
    this.getAllMenuList()
    this.getAllRoleManagement()
    this.getUserManagement()
  },

  methods: {
    // 排序 （序号）
    sort (index) {
      return changSort(index, this.pageNum, this.pageSize)
    },

    // 性别的转化
    getSexText (value) {
      const dto = this.sexData.find(v => v.value === value)
      return dto && dto ? dto.label : ''
    },

    // 角色名的转化
    getRoleText (value) {
      const dto = this.roleData.find(v => v.roleId === value)
      return dto && dto ? dto.roleName : ''
    },

    // 新增
    saveDataForm () {
      Object.keys(this.form).forEach(key => {
        this.form[key] = ''
      })
      this.dialogFormVisible = true
      this.form.menuIdList = []
      this.form.status = '0'
      this.form.sex = '0'
      this.form.password = 'Tjd!888888'
    },

    // 修改
    async handleClick (data) {
      await this.getUserInfo(data.userId)
      this.dialogFormVisible = true
      Object.keys(data).forEach(key => {
        this.form[key] = data[key]
      })
      this.form.menuIdList = this.userInfoForm.menuIdList
    },

    // 关闭dialog框
    closeDialog () {
      this.$refs.dialogForm.resetFields()
      this.dialogFormVisible = false
      this.submitLoading = false
      this.setPermissionsShow = false
      Object.keys(this.form).forEach(key => {
        this.form[key] = ''
      })
    },

    getUserManagement () {
      this.list = []
      this.$store.dispatch('getUserManagement', {
        pageSize: this.pageSize,
        pageNum: this.pageNum,
        queryValue: this.queryValue,
        status: this.status,
        roleId: this.roleId
      }).then(res => {
        this.list = res.data
        this.total = res.total
      })
    },

    saveDataApi () {
      this.$refs.dialogForm.validate(valid => {
        if (!valid) return false
        this.submitLoading = true
        this.form.companyId = 105
        this.form.userType = '01'
        if (!this.form.userId) {
          post('/api/crm/sys/manage/crm/user/addUser', this.form).then(req => {
            if (req && req.code === 200) {
              this.$message({ message: req.msg, type: 'success' })
              this.closeDialog()
              this.getUserManagement()
            } else {
              this.$message({ message: req.msg, type: 'error' })
            }
          }).finally(() => {
            this.submitLoading = false
          })
        } else {
          post('/api/crm/sys/manage/crm/user/editUser', this.form).then(req => {
            if (req && req.code === 200) {
              this.$message({ message: req.msg, type: 'success' })
              this.closeDialog()
              this.getUserManagement()
            } else {
              this.$message({ message: req.msg, type: 'error' })
            }
          }).finally(() => {
            this.submitLoading = false
          })
        }
      })
    },

    deleteDataApi (type) {
      if (type === 'ok') {
        const ids = Array.isArray(this.id) ? '0' : [this.id]
        post('/api/crm/sys/manage/crm/user/removeUser', ids
        ).then(req => {
          if (req && req.code === 200) {
            this.$message({ message: req.msg, type: 'success' })
            this.getUserManagement()
          }
        })
      }
      this.dialogVisible = false
    },

    changeStatus (row) {
      const params = {
        userId: '',
        status: ''
      }
      params.userId = row.userId
      params.status = row.status === '0' ? '1' : '0'
      this.$confirm('是否启用/禁用', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        post('/api/crm/sys/manage/crm/user/changeUserStatus', params).then(req => {
          if (req && req.code === 200) {
            this.$message({ message: '成功', type: 'success' })
          } else {
            this.$message({ message: '失败', type: 'error' })
          }
        }).finally(() => {
          this.getUserManagement()
        })
      })
    },

    // 设置权限
    async handleSetPermissions (data) {
      await this.getUserInfo(data.userId) // 等待数据获取完成
      this.setPermissionsShow = true
      Object.keys(data).forEach(key => {
        this.form[key] = data[key]
      })
      this.form.menuIdList = this.userInfoForm.menuIdList
      this.checkedMenuIds = this.userInfoForm.menuIdList
      this.menuTreeData = this.formatToTree(this.menuData)
      // 延迟设置默认勾选，确保 `menuTreeData` 已渲染
      this.$nextTick(() => {
        if (this.$refs.menuTree) {
          this.$refs.menuTree.setCheckedKeys(this.checkedMenuIds) // 默认勾选节点
        }
      })
    },

    // 格式化数据为树形结构
    formatToTree (data) {
      const map = {}
      const result = []
      data.forEach((item) => (map[item.menuId] = { ...item, children: [] }))
      data.forEach((item) => {
        if (item.parentId !== '-1') {
          // map[item.parentId]?.children.push(map[item.menuId])
          if (map[item.parentId] && map[item.parentId].children) {
            map[item.parentId].children.push(map[item.menuId])
          }
        } else {
          result.push(map[item.menuId])
        }
      })
      return result
    },

    // 勾选变化事件处理
    handleCheckChange (node, isChecked, childrenChecked) {
      this.checkedMenuIds = this.$refs.menuTree.getCheckedKeys()
    },

    // 保存权限操作
    async saveSetPermissionsDataApi () {
      this.submitLoading = true
      this.form.menuIdList = this.checkedMenuIds
      post('/api/crm/sys/manage/crm/user/editUser', this.form).then(req => {
        if (req && req.code === 200) {
          this.$message({ message: req.msg, type: 'success' })
        } else {
          this.$message({ message: req.msg, type: 'error' })
        }
      }).finally(() => {
        this.closeDialog()
        this.getUserManagement()
      })
    },

    resetPassword (row) {
      const params = {
        userId: row.userId,
        password: 'Tjd!888888'
      }
      this.$confirm('是否重置密码为：Tjd!888888', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        post('/api/crm/sys/manage/crm/user/resetUserPwd', params).then(req => {
          if (req && req.code === 200) {
            this.$message({ message: '成功', type: 'success' })
          } else {
            this.$message({ message: '失败', type: 'error' })
          }
        }).finally(() => {
          this.getUserManagement()
        })
      })
    },

    // 重置勾选
    resetSelection () {
      this.$refs.menuTree.setCheckedKeys([])
      this.checkedMenuIds = []
    },

    async getUserInfo (userId) {
      this.userInfoForm = {}
      const res = await this.$store.dispatch('getUserInfo', userId)
      this.userInfoForm = res.data
    },

    // 根据全部角色信息
    getAllRoleManagement (value) {
      this.$store.dispatch('getAllRoleManagement', value).then(res => {
        this.roleData = res.data
      })
    },

    // 根据全部菜单信息
    getAllMenuList (value) {
      this.$store.dispatch('getAllMenuList', value).then(res => {
        this.menuData = res.data
      })
    },

    handleQuery () {
      this.pageNum = 1
      this.getUserManagement()
    },

    handleSizeChange (val) {
      this.pageSize = val
      this.getUserManagement()
    },

    handleCurrentChange (val) {
      this.pageNum = val
      this.getUserManagement()
    },

    handleButtonClick (data) {
      this.id = data.userId
      this.dialogVisible = true
    },

    is_show_button (name) {
      let show = false
      this.$store.state.module1.menu_list.forEach(v => {
        // eslint-disable-next-line eqeqeq
        if (v.path === name) {
          show = true
        }
      })
      return show
    }
  }
}
</script>

<style lang='scss'>
.page_format {
  padding: 56px 20px 140px 20px;
}

.search-form {
  margin-top: 10px;
}

.icon-image {
  width: auto;
  height: auto;
  object-fit: cover;
}
.el-form-item {
  margin-bottom: 20px; /* 增加下方间距 */
}

/* 调整提示文字的行高 */
.el-form-item__error {
  line-height: 1.5; /* 调整错误提示文字的行高 */
  font-size: 14px; /* 可根据需要调整字体大小 */
  color: #f56c6c; /* 确保提示文字清晰 */
}
</style>
